#include "sqlite_demo.h"
#include "global_config.h"
#include "WiFi.h"
#include <sqlite3.h>
#include <SPI.h>
#include <FS.h>
#include "LittleFS.h"
#define DB1_FILE "/littlefs/test1.db"
#define DB2_FILE "/littlefs/test2.db"
#define FORMAT_LITTLEFS_IF_FAILED true


SQLiteDemo sqliteDemo;

const char* data = "Callback function called";
static int callback(void *data, int argc, char **argv, char **azColName) {
   int i;
   Serial.printf("%s: ", (const char*)data);
   for (i = 0; i<argc; i++){
       Serial.printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }
   Serial.printf("\n");
   return 0;
}

int db_open(const char *filename, sqlite3 **db) {
   int rc = sqlite3_open(filename, db);
   if (rc) {
       Serial.printf("Can't open database: %s\n", sqlite3_errmsg(*db));
       return rc;
   } else {
       Serial.printf("Opened database successfully\n");
   }
   return rc;
}

char *zErrMsg = 0;
int db_exec(sqlite3 *db, const char *sql) {
   Serial.println(sql);
   long start = micros();
   int rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
   if (rc != SQLITE_OK) {
       Serial.printf("SQL error: %s\n", zErrMsg);
       sqlite3_free(zErrMsg);
   } else {
       Serial.printf("Operation done successfully\n");
   }
   Serial.print(F("Time taken:"));
   Serial.println(micros()-start);
   return rc;
}

void SQLiteDemo::init() {

    // WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

    // while ( WiFi.status() != WL_CONNECTED ) {
    //     delay ( 500 );
    //     Serial.print ( "." );
    // }
    // Serial.println ( "Connected to WiFi" );
    // Serial.print ( "IP address: " );
    // Serial.println ( WiFi.localIP() );

}

void SQLiteDemo::initSQLiteDemo() {
    Serial.println("init SQLiteDemo");
    sqlite3 *db1;
    sqlite3 *db2;
    int rc;

    if (!LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED, "/littlefs")) {
        Serial.println("Failed to mount file system");
        return;
    }

    // list LITTLEFS contents
    File root = LittleFS.open("/");
    if (!root) {
        Serial.println("- failed to open directory");
        return;
    }
    if (!root.isDirectory()) {
        Serial.println(" - not a directory");
        return;
    }
    File file = root.openNextFile();
    while (file) {
        if (file.isDirectory()) {
            Serial.print("  DIR : ");
            Serial.println(file.name());
        } else {
            Serial.print("  FILE: ");
            Serial.print(file.name());
            Serial.print("\tSIZE: ");
            Serial.println(file.size());
        }
        file = root.openNextFile();
    }

    // remove existing file
    // LittleFS.remove("/test1.db");
    // LittleFS.remove("/test2.db");

    sqlite3_initialize();

    if (db_open(DB1_FILE, &db1))
        return;
    if (db_open(DB2_FILE, &db2))
        return;

    // rc = db_exec(db1, "CREATE TABLE test1 (id INTEGER, content);");
    // if (rc != SQLITE_OK) {
    //     sqlite3_close(db1);
    //     sqlite3_close(db2);
    //     return;
    // }
    // rc = db_exec(db2, "CREATE TABLE test2 (id INTEGER, content);");
    // if (rc != SQLITE_OK) {
    //     sqlite3_close(db1);
    //     sqlite3_close(db2);
    //     return;
    // }

    // rc = db_exec(db1, "INSERT INTO test1 VALUES (1, 'Hello, World from test1');");
    // if (rc != SQLITE_OK) {
    //     sqlite3_close(db1);
    //     sqlite3_close(db2);
    //     return;
    // }
    // rc = db_exec(db2, "INSERT INTO test2 VALUES (1, 'Hello, World from test2');");
    // if (rc != SQLITE_OK) {
    //     sqlite3_close(db1);
    //     sqlite3_close(db2);
    //     return;
    // }

    rc = db_exec(db1, "SELECT * FROM test1");
    if (rc != SQLITE_OK) {
        sqlite3_close(db1);
        sqlite3_close(db2);
        return;
    }
    rc = db_exec(db2, "SELECT * FROM test2");
    if (rc != SQLITE_OK) {
        sqlite3_close(db1);
        sqlite3_close(db2);
        return;
    }

    sqlite3_close(db1);
    sqlite3_close(db2);
}